home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / misc / amag / AM9410_2.lha / Haufenweise / Programme / PoolSupport.c < prev    next >
C/C++ Source or Header  |  1994-07-18  |  6KB  |  217 lines

  1. #include "PoolSupport.h"
  2.  
  3. /*
  4.  * CreatePool13 ist das Gegenstück zu CreatePool von 3.0.
  5.  *          Es kreiert einen Speicher-Pool, aus dem man
  6.  *          anschließend beliebige Stücke holen kann.
  7.  *
  8.  *          Flags sind die üblichen Angaben zum Speicher
  9.  *          wie sie auch bei AllocMem üblich sind
  10.  *
  11.  *          RegionSize ist die Kachelgröße. Immer dann
  12.  *          wenn im Pool für eine Allozierung nicht mehr
  13.  *          genügend Speicher vorhanden ist, wird eine
  14.  *          neue Kachel alloziert.
  15.  *
  16.  *          NewSize gibt die Größe an, ab der bei einer
  17.  *          Allozierung grundsätzlich eine neue Kachel
  18.  *          besorgt wird.
  19.  */
  20.  
  21.  
  22. void *CreatePool13(ULONG Flags,ULONG RegionSize, ULONG NewSize)
  23. {
  24.    struct Pool *poo = 0L;
  25.  
  26.    if (NewSize <= RegionSize)
  27.    {
  28.       if (poo = AllocMem(sizeof(struct Pool),MEMF_CLEAR))
  29.       {
  30.          poo->Flags      = Flags;
  31.          poo->RegionSize = RegionSize;
  32.          poo->NewSize    = NewSize;
  33.  
  34.          NewList(&(poo->MHAnchor));
  35.       }
  36.    }
  37.  
  38.    return poo;
  39. }
  40.  
  41. void DeletePool13(APTR MyPool)
  42. {
  43.    struct MemHeader *mh,*next;
  44.    struct Pool *p = (struct Pool *)MyPool;
  45.  
  46.    if (MyPool != NULL)
  47.    {  if (!IsListEmpty(&(p->MHAnchor)))
  48.       {  mh = (struct MemHeader *)p->MHAnchor.lh_Head;
  49.  
  50.          while ((APTR)mh != &(p->MHAnchor.lh_Tail))
  51.          {  next = (struct MemHeader *)mh->mh_Node.ln_Succ;
  52.             FreeMemHeader(mh);          // dann freigeben
  53.             mh   = next;                // und auf den nächsten
  54.                                         // setzen
  55.          }
  56.       }
  57.       FreeMem(p,sizeof(struct Pool));
  58.    }
  59. }
  60.  
  61. /*
  62.  *  request(): Öffnet einen System-Requester. Aufruf
  63.  *             wie EasyRequest und Printf() !
  64.  *
  65.  *  Input: char *title:     Fenstertiteltext
  66.  *         char *gadgets:   Gadgettexte durch | getrennt
  67.  *         char *text:      Requestertext, Zeilen durch
  68.  *                          \n getrennt
  69.  *
  70.  *  Ergebnis: 1 = linkes Gadget, 0 = rechtes Gadget, 2 = ..
  71.  */
  72.  
  73. #include <intuition/intuition.h>
  74. #include <clib/intuition_protos.h>
  75. #include <dos/dosextens.h>
  76. #include <stdarg.h>
  77.  
  78. long request(char *title, char *gadgets, char *text, ...)
  79. {
  80.     long rc = 0;
  81.     struct EasyStruct textreq = {
  82.         sizeof (struct EasyStruct), 0L,0L,0L,0L};
  83.     struct Process *process;
  84.     struct Window *win;
  85.     va_list ap;
  86.  
  87.     va_start(ap, text);
  88.     /* für Printf-Argumente */
  89.  
  90.     if (process = (struct Process *)FindTask(NULL)) 
  91.     {  if ((long)(win = process->pr_WindowPtr) != -1) 
  92.        {
  93.           textreq.es_Title        = (UBYTE *)title;
  94.           textreq.es_TextFormat   = (UBYTE *)text;
  95.           textreq.es_GadgetFormat = (UBYTE *)gadgets;
  96.  
  97.           rc = EasyRequestArgs(win, &textreq, NULL, ap);
  98.        }
  99.     }
  100.  
  101.     va_end(ap);
  102.     return(rc);
  103. }
  104.  
  105.  
  106. /*
  107.  * AllocPooled13 ist die Funktion, die Speicher aus einem
  108.  *               Pool alloziert. Sie verhält sich wie die
  109.  *               zugehörige 3.0-Funktion. Leider ist bei
  110.  *               der 3.0-Dokumentation nicht geklärt, was
  111.  *               passieren soll, wenn ein Speicherblock
  112.  *               alloziert werden soll, der größer als
  113.  *               RegionSize ist.
  114.  *
  115.  *               Diese Funktion alloziert dann einen 
  116.  *               entsprechend großen Block, damit die
  117.  *               Allozierung stattfinden kann.
  118.  */
  119.  
  120. static BOOL _AllocRegion(struct Pool *p,ULONG Size)
  121. {
  122.    struct MemHeader *mh = 0;
  123.    int poolsize;
  124.  
  125.    poolsize = MAX(p->RegionSize,Size+8);
  126.  
  127.    while (!(mh = AllocMemHeader(poolsize,p->Flags)))
  128.    {  /*struct Task *t = FindTask(0L);
  129.       if (!request(t->tc_Node.ln_Name,"Retry|Cancel",
  130.            "Not enough memory free!\n"
  131.            "Free some and try again")) */
  132.       {  return FALSE; // kein Speicher da
  133.       }
  134.    }
  135.  
  136.    AddHead(&(p->MHAnchor),(struct Node *)mh);
  137.  
  138.    return TRUE;
  139. }
  140.  
  141.  
  142. APTR AllocPooled13(void *MyPool,ULONG Size)
  143. {
  144.    register struct Pool *p = (struct Pool *)MyPool;
  145.    struct MemHeader *mh = 0;
  146.    APTR newmem = 0;
  147.  
  148.    /* Liste noch leer oder großer Bereich gefordert? */
  149.    if ((IsListEmpty(&(p->MHAnchor))) ||
  150.        (Size > p->NewSize))
  151.    {  
  152.       /* dann allozieren */
  153.       if (!_AllocRegion(p,Size))
  154.       {  
  155.          /* ging schief */
  156.          return NULL; 
  157.       }
  158.    }
  159.  
  160.    mh = (struct MemHeader *)p->MHAnchor.lh_Head;
  161.  
  162.    /* bis eine Kachel genügend Speicher enthält */
  163.    while ((APTR)mh != &(p->MHAnchor.lh_Tail))
  164.    {
  165.       if (newmem = AllocateVec(mh,Size))
  166.       {  
  167.          //PutStr("{  return newmem; }\n");
  168.          return newmem; 
  169.       }
  170.       else
  171.       {  mh = (struct MemHeader *)mh->mh_Node.ln_Succ; }
  172.    }
  173.  
  174.    /* wenn man hier ankommt, dann war in den
  175.       Kacheln nicht genügend Speicher. Also eine
  176.       neue Allozieren und von vorn */
  177.  
  178.    if (!_AllocRegion(p,Size))
  179.    {  return NULL; }
  180.    else  /* Rekursiv geht es weiter */
  181.    {  return AllocPooled13(p,Size); }
  182.  
  183. }
  184.  
  185. /*
  186.  * FreePooled13 ist das Gegenstück zu AllocPooled13().
  187.  *
  188.  * WARNUNG:     FreePooled13() ist nicht aufrufkompatibel
  189.  *              zu FreePooled() von 3.0. Es fehlt der 3.
  190.  *              Parameter, der die Länge enthält. Dieser
  191.  *              ist nicht nötig, da für die Allozierung
  192.  *              immer AllocateVec() benutzt wird. Wer
  193.  *              will, kann natürlich einen 3. Dummy-
  194.  *              Parameter einführen.
  195.  */
  196.  
  197. void FreePooled13(void *MyPool, APTR memaddr)
  198. {
  199.    register struct Pool *p = (struct Pool *)MyPool;
  200.    struct MemHeader *mh = 0;
  201.  
  202.    mh = (struct MemHeader *)p->MHAnchor.lh_Head;
  203.  
  204.    /* bis die richtige Kachel gefunden ist */
  205.    while ((APTR)mh != &(p->MHAnchor.lh_Tail))
  206.    {  
  207.       if ((memaddr >= mh->mh_Lower) &&
  208.           (memaddr <  mh->mh_Upper))
  209.       {  DeallocateVec(mh,memaddr); 
  210.          break;
  211.       }
  212.       else
  213.       {  mh = (struct MemHeader *)mh->mh_Node.ln_Succ; }
  214.    }
  215. }
  216.  
  217.